home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-ALPH.{_4 / JENSEN.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  8KB  |  345 lines

  1. #ifndef __ALPHA_JENSEN_H
  2. #define __ALPHA_JENSEN_H
  3.  
  4. #include <asm/compiler.h>
  5.  
  6. /*
  7.  * Defines for the AlphaPC EISA IO and memory address space.
  8.  */
  9.  
  10. /* The Jensen is strange */
  11. #define AUX_IRQ (9)
  12.  
  13. /*
  14.  * NOTE! The memory operations do not set any memory barriers, as it's
  15.  * not needed for cases like a frame buffer that is essentially memory-like.
  16.  * You need to do them by hand if the operations depend on ordering.
  17.  *
  18.  * Similarly, the port IO operations do a "mb" only after a write operation:
  19.  * if an mb is needed before (as in the case of doing memory mapped IO
  20.  * first, and then a port IO operation to the same device), it needs to be
  21.  * done by hand.
  22.  *
  23.  * After the above has bitten me 100 times, I'll give up and just do the
  24.  * mb all the time, but right now I'm hoping this will work out.  Avoiding
  25.  * mb's may potentially be a noticeable speed improvement, but I can't
  26.  * honestly say I've tested it.
  27.  *
  28.  * Handling interrupts that need to do mb's to synchronize to non-interrupts
  29.  * is another fun race area.  Don't do it (because if you do, I'll have to
  30.  * do *everything* with interrupts disabled, ugh).
  31.  */
  32.  
  33. /*
  34.  * EISA Interrupt Acknowledge address
  35.  */
  36. #define EISA_INTA        (IDENT_ADDR + 0x100000000UL)
  37.  
  38. /*
  39.  * FEPROM addresses
  40.  */
  41. #define EISA_FEPROM0        (IDENT_ADDR + 0x180000000UL)
  42. #define EISA_FEPROM1        (IDENT_ADDR + 0x1A0000000UL)
  43.  
  44. /*
  45.  * VL82C106 base address
  46.  */
  47. #define EISA_VL82C106        (IDENT_ADDR + 0x1C0000000UL)
  48.  
  49. /*
  50.  * EISA "Host Address Extension" address (bits 25-31 of the EISA address)
  51.  */
  52. #define EISA_HAE        (IDENT_ADDR + 0x1D0000000UL)
  53.  
  54. /*
  55.  * "SYSCTL" register address
  56.  */
  57. #define EISA_SYSCTL        (IDENT_ADDR + 0x1E0000000UL)
  58.  
  59. /*
  60.  * "spare" register address
  61.  */
  62. #define EISA_SPARE        (IDENT_ADDR + 0x1F0000000UL)
  63.  
  64. /*
  65.  * EISA memory address offset
  66.  */
  67. #define EISA_MEM        (IDENT_ADDR + 0x200000000UL)
  68.  
  69. /*
  70.  * EISA IO address offset
  71.  */
  72. #define EISA_IO            (IDENT_ADDR + 0x300000000UL)
  73.  
  74.  
  75. #ifdef __KERNEL__
  76.  
  77. #ifndef __EXTERN_INLINE
  78. #define __EXTERN_INLINE extern inline
  79. #define __IO_EXTERN_INLINE
  80. #endif
  81.  
  82. /*
  83.  * Change virtual addresses to bus addresses and vv.
  84.  *
  85.  * NOTE! On the Jensen, the physical address is the same
  86.  * as the bus address, but this is not necessarily true on
  87.  * other alpha hardware.
  88.  */
  89. __EXTERN_INLINE unsigned long jensen_virt_to_bus(void * address)
  90. {
  91.     return virt_to_phys(address);
  92. }
  93.  
  94. __EXTERN_INLINE void * jensen_bus_to_virt(unsigned long address)
  95. {
  96.     return phys_to_virt(address);
  97. }
  98.  
  99.  
  100. /*
  101.  * Handle the "host address register". This needs to be set
  102.  * to the high 7 bits of the EISA address.  This is also needed
  103.  * for EISA IO addresses, which are only 16 bits wide (the
  104.  * hae needs to be set to 0).
  105.  *
  106.  * HAE isn't needed for the local IO operations, though.
  107.  */
  108.  
  109. #define JENSEN_HAE_ADDRESS    EISA_HAE
  110. #define JENSEN_HAE_MASK        0x1ffffff
  111.  
  112. __EXTERN_INLINE void jensen_set_hae(unsigned long addr)
  113. {
  114.     /* hae on the Jensen is bits 31:25 shifted right */
  115.     addr >>= 25;
  116.     if (addr != alpha_mv.hae_cache)
  117.         set_hae(addr);
  118. }
  119.  
  120. #define vuip    volatile unsigned int *
  121.  
  122. /*
  123.  * IO functions
  124.  *
  125.  * The "local" functions are those that don't go out to the EISA bus,
  126.  * but instead act on the VL82C106 chip directly.. This is mainly the
  127.  * keyboard, RTC,  printer and first two serial lines..
  128.  *
  129.  * The local stuff makes for some complications, but it seems to be
  130.  * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
  131.  * convinced that I need one of the newer machines.
  132.  */
  133.  
  134. static inline unsigned int jensen_local_inb(unsigned long addr)
  135. {
  136.     return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
  137. }
  138.  
  139. static inline void jensen_local_outb(unsigned char b, unsigned long addr)
  140. {
  141.     *(vuip)((addr << 9) + EISA_VL82C106) = b;
  142.     mb();
  143. }
  144.  
  145. static inline unsigned int jensen_bus_inb(unsigned long addr)
  146. {
  147.     long result;
  148.  
  149.     jensen_set_hae(0);
  150.     result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
  151.     return __kernel_extbl(result, addr & 3);
  152. }
  153.  
  154. static inline void jensen_bus_outb(unsigned char b, unsigned long addr)
  155. {
  156.     jensen_set_hae(0);
  157.     *(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
  158.     mb();
  159. }
  160.  
  161. /*
  162.  * It seems gcc is not very good at optimizing away logical
  163.  * operations that result in operations across inline functions.
  164.  * Which is why this is a macro.
  165.  */
  166.  
  167. #define jensen_is_local(addr) ( \
  168. /* keyboard */    (addr == 0x60 || addr == 0x64) || \
  169. /* RTC */    (addr == 0x170 || addr == 0x171) || \
  170. /* mb COM2 */    (addr >= 0x2f8 && addr <= 0x2ff) || \
  171. /* mb LPT1 */    (addr >= 0x3bc && addr <= 0x3be) || \
  172. /* mb COM2 */    (addr >= 0x3f8 && addr <= 0x3ff))
  173.  
  174. __EXTERN_INLINE unsigned int jensen_inb(unsigned long addr)
  175. {
  176.     if (jensen_is_local(addr))
  177.         return jensen_local_inb(addr);
  178.     else
  179.         return jensen_bus_inb(addr);
  180. }
  181.  
  182. __EXTERN_INLINE void jensen_outb(unsigned char b, unsigned long addr)
  183. {
  184.     if (jensen_is_local(addr))
  185.         jensen_local_outb(b, addr);
  186.     else
  187.         jensen_bus_outb(b, addr);
  188. }
  189.  
  190. __EXTERN_INLINE unsigned int jensen_inw(unsigned long addr)
  191. {
  192.     long result;
  193.  
  194.     jensen_set_hae(0);
  195.     result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
  196.     result >>= (addr & 3) * 8;
  197.     return 0xffffUL & result;
  198. }
  199.  
  200. __EXTERN_INLINE unsigned int jensen_inl(unsigned long addr)
  201. {
  202.     jensen_set_hae(0);
  203.     return *(vuip) ((addr << 7) + EISA_IO + 0x60);
  204. }
  205.  
  206. __EXTERN_INLINE void jensen_outw(unsigned short b, unsigned long addr)
  207. {
  208.     jensen_set_hae(0);
  209.     *(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
  210.     mb();
  211. }
  212.  
  213. __EXTERN_INLINE void jensen_outl(unsigned int b, unsigned long addr)
  214. {
  215.     jensen_set_hae(0);
  216.     *(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
  217.     mb();
  218. }
  219.  
  220. /*
  221.  * Memory functions.
  222.  */
  223.  
  224. __EXTERN_INLINE unsigned long jensen_readb(unsigned long addr)
  225. {
  226.     long result;
  227.  
  228.     jensen_set_hae(addr);
  229.     addr &= JENSEN_HAE_MASK;
  230.     result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
  231.     result >>= (addr & 3) * 8;
  232.     return 0xffUL & result;
  233. }
  234.  
  235. __EXTERN_INLINE unsigned long jensen_readw(unsigned long addr)
  236. {
  237.     long result;
  238.  
  239.     jensen_set_hae(addr);
  240.     addr &= JENSEN_HAE_MASK;
  241.     result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
  242.     result >>= (addr & 3) * 8;
  243.     return 0xffffUL & result;
  244. }
  245.  
  246. __EXTERN_INLINE unsigned long jensen_readl(unsigned long addr)
  247. {
  248.     jensen_set_hae(addr);
  249.     addr &= JENSEN_HAE_MASK;
  250.     return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
  251. }
  252.  
  253. __EXTERN_INLINE unsigned long jensen_readq(unsigned long addr)
  254. {
  255.     unsigned long r0, r1;
  256.  
  257.     jensen_set_hae(addr);
  258.     addr &= JENSEN_HAE_MASK;
  259.     addr = (addr << 7) + EISA_MEM + 0x60;
  260.     r0 = *(vuip) (addr);
  261.     r1 = *(vuip) (addr + (4 << 7));
  262.     return r1 << 32 | r0;
  263. }
  264.  
  265. __EXTERN_INLINE void jensen_writeb(unsigned char b, unsigned long addr)
  266. {
  267.     jensen_set_hae(addr);
  268.     addr &= JENSEN_HAE_MASK;
  269.     *(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
  270. }
  271.  
  272. __EXTERN_INLINE void jensen_writew(unsigned short b, unsigned long addr)
  273. {
  274.     jensen_set_hae(addr);
  275.     addr &= JENSEN_HAE_MASK;
  276.     *(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
  277. }
  278.  
  279. __EXTERN_INLINE void jensen_writel(unsigned int b, unsigned long addr)
  280. {
  281.     jensen_set_hae(addr);
  282.     addr &= JENSEN_HAE_MASK;
  283.     *(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
  284. }
  285.  
  286. __EXTERN_INLINE void jensen_writeq(unsigned long b, unsigned long addr)
  287. {
  288.     jensen_set_hae(addr);
  289.     addr &= JENSEN_HAE_MASK;
  290.     addr = (addr << 7) + EISA_MEM + 0x60;
  291.     *(vuip) (addr) = b;
  292.     *(vuip) (addr + (4 << 7)) = b >> 32;
  293. }
  294.  
  295. /* Find the DENSE memory area for a given bus address.
  296.    Whee, there is none.  */
  297.  
  298. __EXTERN_INLINE unsigned long jensen_dense_mem(unsigned long addr)
  299. {
  300.     return 0;
  301. }
  302.  
  303. #undef vuip
  304.  
  305. #ifdef __WANT_IO_DEF
  306.  
  307. #define virt_to_bus    jensen_virt_to_bus
  308. #define bus_to_virt    jensen_bus_to_virt
  309. #define __inb        jensen_inb
  310. #define __inw        jensen_inw
  311. #define __inl        jensen_inl
  312. #define __outb        jensen_outb
  313. #define __outw        jensen_outw
  314. #define __outl        jensen_outl
  315. #define __readb        jensen_readb
  316. #define __readw        jensen_readw
  317. #define __writeb    jensen_writeb
  318. #define __writew    jensen_writew
  319. #define __readl        jensen_readl
  320. #define __readq        jensen_readq
  321. #define __writel    jensen_writel
  322. #define __writeq    jensen_writeq
  323. #define dense_mem    jensen_dense_mem
  324.  
  325. /*
  326.  * The above have so much overhead that it probably doesn't make
  327.  * sense to have them inlined (better icache behaviour).
  328.  */
  329. #define inb(port) \
  330. (__builtin_constant_p((port))?__inb(port):_inb(port))
  331.  
  332. #define outb(x, port) \
  333. (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
  334.  
  335. #endif /* __WANT_IO_DEF */
  336.  
  337. #ifdef __IO_EXTERN_INLINE
  338. #undef __EXTERN_INLINE
  339. #undef __IO_EXTERN_INLINE
  340. #endif
  341.  
  342. #endif /* __KERNEL__ */
  343.  
  344. #endif /* __ALPHA_JENSEN_H */
  345.